home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
desktop
/
profft.zip
/
SOURCE
/
MAINWIN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-29
|
41KB
|
1,291 lines
/****************************************************************************
MAINWIN.CPP Denne filen inneholder (i denne rekkef°lgen):
*****************************************************************************
TMainWindow::TMainWindow(LPSTR ATitle) : TMDIFrame(ATitle, APP_NAME)
TMainWindow::~TMainWindow()
void TMainWindow::GetWindowClass(WNDCLASS& wc)
LPSTR TMainWindow::GetClassName()
void TMainWindow::CMFileOpen(TMessage&)
void TMainWindow::CMFileSaveAs(TMessage&)
void TMainWindow::CMEditCut(TMessage&)
void TMainWindow::CMEditCopy(TMessage&)
void TMainWindow::CMEditPaste(TMessage&)
void TMainWindow::CMTransformFFT(TMessage&)
void TMainWindow::CMTransformIFFT(TMessage&)
void TMainWindow::CMTransformInvert(TMessage&)
void TMainWindow::CMFilterLowpass(TMessage&)
void TMainWindow::CMFilterHighpass(TMessage&)
void TMainWindow::CMFilterBandpass(TMessage&)
void TMainWindow::CMFilterBandstop(TMessage&)
void TMainWindow::CMFilterBWLowpass(TMessage&)
void TMainWindow::CMFilterBWHighpass(TMessage&)
void TMainWindow::CMFilterFreehand(TMessage&)
void TMainWindow::CMFilterOptions(TMessage&)
void TMainWindow::CMHelpAbout(TMessage&)
void TMainWindow::CMHelpIndex(TMessage&)
BOOL TMainWindow::CheckForHelp(int CM_ID)
BOOL TMainWindow::CanClose()
void TMainWindow::ChangeRubber()
HPALETTE TMainWindow::CreateGrayscalePalette()
void TMainWindow::SetupWindow()
PTWindowsObject TMainWindow::CreateChild(LPSTR FileName,
BITMAPINFO *bmpInfo, HANDLE hBitmap)
PTWindowsObject TMainWindow::CreateComplexChild(LPSTR FileName,
HANDLE hComplexPict, BITMAPINFO *bmpInfo, HANDLE hBitmap)
void TMainWindow::SetRubberSize(int iSize)
int TMainWindow::GetRubberSize()
BOOL TMainWindow::WMQueryNewPalette(TMessage&)
void TMainWindow::WMIdle(TMessage& Msg)
void TMainWindow::WMDrawClipboard(TMessage& Msg)
void TMainWindow::WMChangeCBChain(TMessage& Msg)
void TMainWindow::CreateClipboardChild()
void TMainWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
void TMainWindow::WriteBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
BOOL TMainWindow::OpenDIB(int TheFile, LPSTR FileName)
BOOL TMainWindow::LoadBitmapFile(LPSTR Name)
BOOL TMainWindow::SaveBitmapFile(LPSTR Name)
****************************************************************************/
#include <owl.h>
#include <filedial.h>
#include <dir.h>
#include <string.h>
#pragma hdrstop
#include "profftid.h" // Symbolske konstanter
#include "profft.h" // Klassedefinisjoner
#include "prcomp.h"
TMainWindow::TMainWindow(LPSTR ATitle) : TMDIFrame(ATitle, APP_NAME)
/****************************************************************************
Setter opp en del standardparametre og klargj°r noen programressurser.
Kaller ogsσ superklassen sin konstruktor.
LPSTR ATitle Tittelen pσ hovedvinduet.
Kodet av: MK
Modifisert: MK 01.04.92 La inn menyvalg i.h.t. kons.spek.
MK 04.04.92 Flere menyvalg.
MK 23.04.92 Flere menyvalg.
MK 25.04.92 Clipboardfunksjoner.
LW/MK 26.04.92 Flere menyvalg + fillagring.
*****************************************************************************/
{
prcomplex far *z;
int i;
// Setter hvilken meny som skal fσ oversikten over σpne vinduer.
ChildMenuPos = 4;
// Brukeren har hittil ikke trykket hjelp.
bHelp = FALSE;
// Default st°rrelse pσ viskelµret som brukes ved frihσndsfiltrering.
iRubberSize = 10;
// Det er ikke allokert noen brush til viskelµret ennσ.
hRubber = NULL;
// Cursoren til viskelµret er ikke laget ennσ
hcrRubber = NULL;
// Vis timeglasset mens vi lager tabellen.
hcrWait = LoadCursor(NULL, IDC_WAIT);
// Allokerer minne til tabellen som benyttes ved oppslag ved
// konvertering av BYTE til et komplekst tall.
hByteToComplexTable = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 256*sizeof(prcomplex));
// Her fyller vi inn tallene i tabellen en gang for alle.
if (hByteToComplexTable!=NULL)
{
z = (prcomplex far *)GlobalLock(hByteToComplexTable);
for (i=0;i<=255;i++)
{
z[i].re = (real)i;
z[i].im = (real)0;
}
GlobalUnlock(hByteToComplexTable);
}
else
MessageBox(HWindow, "TMainWindow::TMainWindow hByteToRealTable==NULL", ERROR_CAPTION, MB_OK);
};
TMainWindow::~TMainWindow()
/****************************************************************************
Rydder opp de ressursene som TMainWindow har allokert.
Kodet av: MK
Modifisert: MK 23.04.92 Viskelµrressurser..
*****************************************************************************/
{
// Sletter de ressursene som brukes i forbindelse med vσr spesielle
// cursor ved frihσndsfiltrering. MERK! Disse allokeres ikke i
// konstruktoren men i TMainWindow::SetupWindow
SelectObject(hdcBitmap, hbmOld);
DeleteDC(hdcBitmap);
DeleteObject(hbm);
GlobalUnlock(hmemAND);
GlobalUnlock(hmemXOR);
GlobalFree(hmemAND);
GlobalFree(hmemXOR);
// Kobler oss vekk fra Clipboardviewer kjeden
ChangeClipboardChain(HWindow, hwndNextViewer);
// Sletter grσtonepaletten. MERK! Denne allokeres i TMainWindow::SetupWindow
DeleteObject(hPal);
// Hvis vi fortsatt har en aktivt viskelµrcursor, slett dette
if (hcrRubber!=NULL)
DestroyCursor(hcrRubber);
// Slett viskelµrpennen
if (hRubber!=NULL)
DeleteObject(hRubber);
// Dealloker tabellen som konverterer BYTE til komplekse tall
if (hByteToComplexTable!=NULL)
GlobalFree(hByteToComplexTable);
TMDIFrame::~TMDIFrame();
}
void TMainWindow::GetWindowClass(WNDCLASS& wc)
/****************************************************************************
Henter vindusklassen og standardikon for vinduet.
Kodet av: MK 28.04.92
*****************************************************************************/
{
TMDIFrame::GetWindowClass(wc);
wc.hIcon = LoadIcon(wc.hInstance, "COMPLEX");
}
LPSTR TMainWindow::GetClassName()
/****************************************************************************
Returnerer vindusklassen.
Kodet av: MK 28.04.92
*****************************************************************************/
{
return "PROfft:MainWindow";
}
void TMainWindow::CMFileOpen(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Open fra menyen. Gir brukeren en filσpne
dialogboks og fors°ker σ laste valgt fil hvis brukeren trykker OK
button.
Kodet av: MK 03.04.92
*****************************************************************************/
{
char TempName [MAXPATH];
char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
HCURSOR hcrOld;
// Hvis brukeren ikke trykket hjelp
if (!CheckForHelp(CM_FILEOPEN))
{
// Hvis brukeren velger fil og trykker OK sσ fors°k σ hent fil
if (GetApplication()->ExecDialog( new TPROfftFileDialog
(this, SD_FILEOPEN, strcpy(TempName, "*.bmp"))) == IDOK )
{
hcrOld = SetCursor(hcrWait);
// Hent fil
LoadBitmapFile(TempName);
SetCursor(hcrOld);
}
}
}
void TMainWindow::CMFileSaveAs(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Save fra menyen. Gir brukeren en fillagre
dialogboks og fors°ker σ lagre valgt fil hvis brukeren trykker OK
button.
Kodet av: MK 26.04.92
*****************************************************************************/
{
char TempName [MAXPATH];
char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
HCURSOR hcrOld;
// Hvis brukeren ikke trykket hjelp
if (!CheckForHelp(CM_FILESAVEAS))
{
// Hvis brukeren gir et filnavn og trykker OK
if (GetApplication()->ExecDialog( new TPROfftFileDialog
(this, SD_FILESAVE, strcpy(TempName, "*.bmp"))) == IDOK )
{
hcrOld = SetCursor(hcrWait);
// Fors°k σ lagre fil
SaveBitmapFile(TempName);
SetCursor(hcrOld);
}
}
}
void TMainWindow::CMEditCut(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Cut fra menyen. Denne kaller rutinen som
kopierer bitmaprepresentasjonen av det aktive vinduet til clipboard og
gir deretter objektet (vinduet) beskjed om σ fjerne seg selv.
Kodet av: MK 26.04.92
*****************************************************************************/
{
// Hvis brukeren ikke trykket hjelp
if (!CheckForHelp(CM_EDITCUT))
{
// Hvis vi har et aktivt barnevindu..
if (ActiveChild!=NULL)
{
// Kopier til clipboard
((TGenericPicWindow *)ActiveChild)->EditCopy();
// Be vinduet fjerne seg selv
SendMessage(((TGenericPicWindow *)ActiveChild)->HWindow, WM_CLOSE, 0, 0L);
}
}
}
void TMainWindow::CMEditCopy(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Edit fra menyen. Denne kaller rutinen som
kopierer bitmaprepresentasjonen av det aktive vinduet til clipboard.
Kodet av: MK 26.04.92
*****************************************************************************/
{
// Hvis ikke hjelpemodus
if (!CheckForHelp(CM_EDITCOPY))
{
// Hvis vi har et aktivt barnevindu..
if (ActiveChild!=NULL)
((TGenericPicWindow *)ActiveChild)->EditCopy();
}
}
void TMainWindow::CMEditPaste(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Paste fra menyen. Denne kaller rutinen som
fors°ker σ lage et TPictureWindow objekt fra clipboard. OBS! Vi
supporterer kun DIB (Device Independent Bitmap) fra clipboard..
Kodet av: MK 26.04.92
*****************************************************************************/
{
// Hvis ikke hjelpemodus..
if (!CheckForHelp(CM_EDITCOPY))
{
// Lag TPictureWindow objekt fra clipboard
CreateClipboardChild();
}
}
void TMainWindow::CMTransformFFT(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger FFT fra menyen. Denne kaller rutinen som
ber TPictureWindow om σ FFT seg selv.
Kodet av: MK
*****************************************************************************/
{
// Hvis ikke hjelpemodus
if (!CheckForHelp(CM_TRANSFFT))
{
// Hvis vi har et aktivt barnevindu
if (ActiveChild!=NULL)
((TPictureWindow *)ActiveChild)->PerformFFT();
}
}
void TMainWindow::CMTransformIFFT(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger IFFT fra menyen. Denne kaller rutinen som
ber TComplexWindow om σ IFFT seg selv.
Kodet av: MK
*****************************************************************************/
{
if (!CheckForHelp(CM_TRANSIFFT))
{
if (ActiveChild!=NULL)
((TComplexWindow *)ActiveChild)->PerformIFFT();
}
}
void TMainWindow::CMTransformInvert(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Invert fra menyen. Denne kaller rutinen som
ber TPictureWindow om σ invertere seg selv.
Kodet av: MK
*****************************************************************************/
{
HCURSOR hcrOld;
if (!CheckForHelp(CM_TRANSINVERT))
{
if (ActiveChild!=NULL)
{
hcrOld = SetCursor(hcrWait);
((TPictureWindow *)ActiveChild)->Invert();
SetCursor(hcrOld);
}
}
}
/****************************************************************************
CMFilter* rutinene under setter filtertype i det aktive TComplexWindow
objektet og kaller deretter den aktuelle dialogboksen for det aktuelle
filteret.
For lavpass og h°ypass filtrene (inkludert Butterworth) kalles
ExecuteSmallDialog() som er den dialogboksen som lar deg velge en stk.
radius.
For de andre kalles ExecuteLargeDialog() som lar deg velge to radiuser.
Ved valg av radiuser vil filtrene vise seg i det aktuelle
TComplexWindow objektet.
Kodet av: MK
*****************************************************************************/
void TMainWindow::CMFilterLowpass(TMessage&)
{
if (!CheckForHelp(CM_FILTERLOWPASS))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERLOWPASS;
((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
}
}
void TMainWindow::CMFilterHighpass(TMessage&)
{
if (!CheckForHelp(CM_FILTERHIGHPASS))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERHIGHPASS;
((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
}
}
void TMainWindow::CMFilterBandpass(TMessage&)
{
if (!CheckForHelp(CM_FILTERBANDPASS))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBANDPASS;
((TComplexWindow *)ActiveChild)->ExecuteLargeDialog();
}
}
void TMainWindow::CMFilterBandstop(TMessage&)
{
if (!CheckForHelp(CM_FILTERBANDSTOP))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBANDSTOP;
((TComplexWindow *)ActiveChild)->ExecuteLargeDialog();
}
}
void TMainWindow::CMFilterBWLowpass(TMessage&)
{
if (!CheckForHelp(CM_FILTERBWLOWPASS))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBWLOWPASS;
((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
}
}
void TMainWindow::CMFilterBWHighpass(TMessage&)
{
if (!CheckForHelp(CM_FILTERBWHIGHPASS))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBWHIGHPASS;
((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
}
}
void TMainWindow::CMFilterFreehand(TMessage&)
/****************************************************************************
Kalles nσr brukeren velger Freehand fra menyen. Denne kaller rutinen som
utf°rer frihσndsfilteret. Merk! Den starter ikke opp noen dialogboks som
de andre filtrene, men utf°rer filtreringen direkte i bildet. Den
forutsetter at brukeren allerede har tegnet inn med r°dt de omrσdene
som °nskes fjernet.
Kodet av: MK 23.04.92
*****************************************************************************/
{
if (!CheckForHelp(CM_FILTERFREEHAND))
{
((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERFREEHAND;
((TComplexWindow *)ActiveChild)->PrepareToExecuteFilter();
}
}
void TMainWindow::CMFilterOptions(TMessage&)
/****************************************************************************
Kaller Options boksen. Denne lar deg forandre pσ standardverdiene
bShiftCenter Hvorvidt det komplekse bildet skal sentreres
iRubberSize St°rrelsen pσ viskelµret
iCircleRubber Forteller hvorvidt viskelµret skal vµre rundt eller
firkantet.
Kodet av: MK 21.04.92
Oppdatert: MK 25.04.92 St°tte for forskjellige typer viskelµr
(rundt eller firkantet).
*****************************************************************************/
{
TOptions *tdOptions;
if (!CheckForHelp(CM_FILTEROPTIONS))
{
// Instansier ny dialogboks
tdOptions = new TOptions(this, "RUBBER");
if (tdOptions==NULL)
MessageBox(HWindow, "TMainWindow::CMFilterOptions tdOptions==NULL",
ERROR_CAPTION, MB_ERROR);
else
// Vis dialogboksen og oppdater standardverdiene hvis brukeren
// tastet OK.
GetApplication()->ExecDialog(tdOptions);
}
}
void TMainWindow::CMHelpAbout(TMessage&)
/****************************************************************************
Kaller opp About dialogboksen. Denne viser bare hvem som stσr bak
dette systemet.
Kodet av: MK 03.04.92
*****************************************************************************/
{
TDialog *tdAbout;
tdAbout = new TDialog(this, "ABOUT");
if (tdAbout!=NULL)
{
GetApplication()->ExecDialog(tdAbout);
}
else
MessageBox(HWindow, "TMainWindow::CMHelpAbout tdAbout==NULL",
ERROR_CAPTION, MB_ICONEXCLAMATION | MB_OK);
}
void TMainWindow::CMHelpIndex(TMessage&)
/****************************************************************************
Kaller opp Windows hjelpesystemet og viser innholdsfortegnelsen.
Kodet av: MK/RI 03.04.92
*****************************************************************************/
{
WinHelp(HWindow, HELP_FILE_NAME, HELP_INDEX, (DWORD) 0);
}
#pragma argsused
BOOL TMainWindow::CheckForHelp(int CM_ID)
/****************************************************************************
Denne er implementert for σ st°tte context sensitive hjelp for meny-
valgene. Forel°pig har ikke hjelpefilen context sensitive hjelp, sσ
vi kaller bare opp indexen. Alle menyvalgene kaller denne for σ sjekke
om brukeren faktisk °nsker hjelp.
Returnerer: TRUE Hvis brukeren °nsket hjelp (trykket shift-F1)
FALSE Ellers
Kodet av: MK/RI 03.04.92
*****************************************************************************/
{
// Hvis vi er i hjelpemodus
if (bHelp)
{
bHelp = FALSE;
// Kall opp hjelpesystemet
WinHelp(HWindow, HELP_FILE_NAME, HELP_INDEX, (DWORD) 0);
// Si ifra til kalleren om at det var hjelp som var °nsket.
return TRUE;
}
else
return FALSE;
}
BOOL TMainWindow::CanClose()
/****************************************************************************
Denne sjekker om det finnes noen aktive vinduer. Hvis det gj°r det sσ
advarer vi brukeren om at han b°r lagre f°r han slutter. Hvis brukeren
trykker Cancel avsluttes ikke programmet allikevel.
Returnerer: TRUE Hvis det ikke finnes aktivt barnevinduet eller
hvis det finnes aktivt barnevindu og brukeren
trykker OK i advarselsboksen.
FALSE ellers.
Kodet av: MK 03.04.92
*****************************************************************************/
{
int iMsgBox;
iMsgBox=IDOK;
// Hvis det finnes noe aktivt barnevindu..
if (ActiveChild!=NULL)
iMsgBox=MessageBox(HWindow, "Any changes not saved will be lost.\nDo you really want to exit PROfft?",
"PROfft - Warning", MB_OKCANCEL);
return iMsgBox==IDOK?TRUE:FALSE;
}
void TMainWindow::ChangeRubber()
/****************************************************************************
Denne lager en cursor som skal vµre aktiv i TComplexWindow objektene.
Cursoren blir laget ut i fra st°rrelse og form som er valgt i
Options.
Kodet av: MK 23.04.92
*****************************************************************************/
{
HPEN hpenB;
hpenB = GetStockObject(BLACK_PEN);
// Oppretter AND og XOR mask for cursoren
SelectObject(hdcBitmap, hbrWhite);
PatBlt(hdcBitmap, 0, 0, cxCursor, cyCursor, PATCOPY);
SelectObject(hdcBitmap, hbrBlack);
SelectObject(hdcBitmap, hpenB);
// Tegner inn cursorformen
if (bCircleRubber)
Ellipse(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
else
Rectangle(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
GetBitmapBits(hbm, (DWORD)cbSize, lpAND);
SelectObject(hdcBitmap, hbrBlack);
PatBlt(hdcBitmap, 0, 0, cxCursor, cyCursor, PATCOPY);
SelectObject(hdcBitmap, hbrWhite);
SelectObject(hdcBitmap, hpenB);
if (bCircleRubber)
Ellipse(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
else
Rectangle(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
GetBitmapBits(hbm, (DWORD)cbSize, lpXOR);
// Hvis vi har en gammel cursor, slett denne
if (hcrRubber!=NULL)
DestroyCursor(hcrRubber);
// Lag ny cursor
hcrRubber = CreateCursor(GetApplication()->hInstance,
iRubberSize/2, iRubberSize/2,
cxCursor, cyCursor,
lpAND, lpXOR);
}
HPALETTE TMainWindow::CreateGrayscalePalette()
/****************************************************************************
Lager en grσtonepalette som inneholder opptil 256 grσtoner.
Returnerer: HPALETTE En Handle til en slik grσtonepalette.
Kodet av: MK 03.04.92
*****************************************************************************/
{
LOCALHANDLE hLocalMem;
LOGPALETTE *plp;
HPALETTE hPal;
int i, nGrayLevel;
// Alloker midlertidig arbeidsminne til paletten
hLocalMem = LocalAlloc (LMEM_MOVEABLE, sizeof(LOGPALETTE) + 256 *
sizeof(PALETTEENTRY));
if (hLocalMem==NULL)
MessageBox(HWindow, "TMainWindow::CreateGrayscalePalette LocalAlloc(Palette)==NULL",
ERROR_CAPTION, MB_ICONEXCLAMATION | MB_OK);
else
{
plp = (LOGPALETTE *) LocalLock(hLocalMem);
// Sett palette dataene
plp->palVersion = 0x300;
plp->palNumEntries = 256;
// Lager alle 256 grσtonene.
for (i=0;i<=255;i++)
{
nGrayLevel = i;
plp->palPalEntry[i].peRed = nGrayLevel;
plp->palPalEntry[i].peGreen = nGrayLevel;
plp->palPalEntry[i].peBlue = nGrayLevel;
plp->palPalEntry[i].peFlags = 0;
}
// Oppretter paletten som et Windowsobjekt.
hPal = CreatePalette(plp);
// Frigj°r midlertidig arbeidsomrσde
LocalUnlock(hLocalMem);
LocalFree(hLocalMem);
if (hPal==NULL)
{
MessageBox(HWindow, "CreateGrayScalePalette failed..", ERROR_CAPTION, MB_OK);
return NULL;
}
else
return hPal;
}
return NULL;
}
void TMainWindow::SetupWindow()
/****************************************************************************
Denne ordner flere ting som har med hovedvinduet σ gj°re.
Den lager viskelµrpennen (r°d). Den setter alle menyvalgene slik de skal
vµre nσr programmet starter (slik at man ikke kan velge f.eks. FFT uten
σ ha noe aktivt bilde). Lager grσtonepaletten. Kobler vσr applikasjon
til clipboardet som en "clipboard viewer". Allokerer minne til vσr
viskelµrcursor. Setter standard viskelµrst°rrelse.
Selv om ting som paletten og viskelµret egentlig kunne h°re til hvert enkelt
barnevindu, har vi valgt σ si at disse tilh°rer hovedvinduet og at
alle barnevinduene har samme palette og viskelµr.
Kodet av: MK
*****************************************************************************/
{
int i;
HMENU hMenu;
HCURSOR hcrOld;
BOOL bError;
HDC hdc;
hMenu=GetMenu(HWindow);
hRubber = CreatePen(PS_SOLID, iRubberSize, 0);
// Slσr av alle menyvalg som ikke skal kunne brukes f°r vi har
// et vindusobjekt σ jobbe med.
for (i=CM_TRANSFFT;i<=CM_TRANSINVERT;i++)
EnableMenuItem(hMenu, i, MF_GRAYED);
for (i=CM_FILTERLOWPASS;i<CM_FILTERFREEHAND;i++)
EnableMenuItem(hMenu, i, MF_GRAYED);
EnableMenuItem(hMenu, CM_FILTERFREEHAND, MF_GRAYED);
EnableMenuItem(hMenu, CM_EDITCOPY, MF_GRAYED);
EnableMenuItem(hMenu, CM_EDITCUT, MF_GRAYED);
EnableMenuItem(hMenu, CM_FILESAVEAS, MF_GRAYED);
TMDIFrame::SetupWindow();
hwndNextViewer = SetClipboardViewer(HWindow);
EnableMenuItem(hMenu, CM_EDITPASTE, IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
hPal = CreateGrayscalePalette();
cxCursor = GetSystemMetrics(SM_CXCURSOR);
cyCursor = GetSystemMetrics(SM_CYCURSOR);
hbm = CreateBitmap(cxCursor, cyCursor, 1, 1, NULL);
hdc = GetDC(HWindow);
hdcBitmap = CreateCompatibleDC(hdc);
ReleaseDC(HWindow, hdc);
hbmOld = SelectObject(hdcBitmap, hbm);
cbSize = (cxCursor/8)*cyCursor;
bError = FALSE;
hmemAND = GlobalAlloc(GMEM_MOVEABLE, (DWORD) cbSize);
if (hmemAND!=NULL)
{
lpAND = GlobalLock(hmemAND);
hmemXOR = GlobalAlloc(GMEM_MOVEABLE, (DWORD) cbSize);
if (hmemXOR!=NULL)
{
lpXOR=GlobalLock(hmemXOR);
hbrWhite = GetStockObject(WHITE_BRUSH);
hbrBlack = GetStockObject(BLACK_BRUSH);
}
else
bError = TRUE;
}
else
bError = TRUE;
if (bError)
MessageBox(HWindow, "Error allocating memory for rubber cursor..", ERROR_CAPTION, MB_ERROR);
SetRubberSize(iRubberSize);
}
PTWindowsObject TMainWindow::CreateChild(LPSTR FileName,
BITMAPINFO *bmpInfo, HANDLE hBitmap)
/****************************************************************************
Oppretter et nytt TPictureWindow objekt med ferdige initialiserte data.
LPSTR FileName Opphavet til objektet (filnavn eller clipboard).
BITMAPINFO *bmpInfo Ferdig initialisert struktur som inneholder bilde-
st°rrelse o.l.
HANDLE hBitmap Handle til ferdig allokert og initialisert bitmap.
Returnerer: Peker til det aktuelle TPictureWindow objektet.
Kodet av: MK
*****************************************************************************/
{
return GetApplication()->MakeWindow(
new TPictureWindow(this, FileName, bmpInfo, hBitmap));
}
PTWindowsObject TMainWindow::CreateComplexChild(LPSTR FileName,
HANDLE hComplexPict, BITMAPINFO *bmpInfo, HANDLE hBitmap)
/****************************************************************************
Oppretter et nytt TComplexWindow objekt med ferdige initialiserte data.
LPSTR FileName Opphavet til objektet (filnavn eller clipboard).
HANDLE hComplexPict Handle til ferdig allokert komplekst bilde.
BITMAPINFO *bmpInfo Ferdig initialisert struktur som inneholder bilde-
st°rrelse o.l.
HANDLE hBitmap Handle til ferdig allokert og initialisert bitmap.
Returnerer: Peker til det aktuelle TComplexWindow objektet.
Kodet av: MK
*****************************************************************************/
{
return GetApplication()->MakeWindow(
new TComplexWindow(this, FileName, hComplexPict,
bmpInfo, hBitmap));
}
void TMainWindow::SetRubberSize(int iSize)
/****************************************************************************
Forandrer pσ st°rrelsen til viskelµret som brukes ved frihσnds-
filtrering. Lager ny viskelµrcursor.
int iSize Den nye st°rrelsen pσ viskelµret.
Kodet av: MK
Oppdatert: MK 23.04.92
*****************************************************************************/
{
// Setter ny standardst°rrelse
iRubberSize = iSize;
// Forandrer pσ cursoren
ChangeRubber();
// Fjerner evt. gammel og lager ny viskelµrpenn.
if (hRubber!=NULL)
DeleteObject(hRubber);
hRubber = CreatePen(PS_SOLID, iRubberSize, 0);
}
int TMainWindow::GetRubberSize()
/****************************************************************************
Returnerer st°rrelsen pσ viskelµret.
Kodet av: MK
*****************************************************************************/
{
return iRubberSize;
}
BOOL TMainWindow::WMQueryNewPalette(TMessage&)
/****************************************************************************
Denne mottar melding fra Windows om denne applikasjonen °nsker σ forandre
pσ paletten. Det vil vi, sσ det gj°r vi!
Returnerer: TRUE Hvis vi forandret paletten.
FALSE Hvis ikke.
Kodet av: MK 03.04.92
*****************************************************************************/
{
HDC hdc;
hdc=GetDC(HWindow);
SelectPalette(hdc, hPal, FALSE);
if (RealizePalette(hdc)>0)
{
ReleaseDC(HWindow, hdc);
InvalidateRect(HWindow, NULL, TRUE);
return TRUE;
}
else
{
ReleaseDC(HWindow, hdc);
return FALSE;
}
}
void TMainWindow::WMIdle(TMessage& Msg)
/****************************************************************************
Denne kalles nσr vi befinner oss i menyen uten σ foreta oss noe. Den skal
passe pσ at hvis vi trykker shift F1 sσ settes hjelpeflagget for det
aktuelle valget og denne kalles.
TMessage& Msg Om vi er i menyen.
Kodet av: MK
*****************************************************************************/
{
// Hvis vi er i menyen og brukeren trykker shift F1
if ((Msg.WParam == MSGF_MENU) &&
(GetKeyState(VK_F1) & 0x8000))
{
// Sett hjelpeflagget og lat som om brukeren trykket F1
// for σ kalle den aktuelle rutinen. De aktuelle rutinene
// sjekker sσ igjen om hjelpeflagget er satt og starter
// hjelpen hvis det er tilfelle.
bHelp = TRUE;
PostMessage(HWindow, WM_KEYDOWN, VK_RETURN, 0L);
}
}
void TMainWindow::WMDrawClipboard(TMessage& Msg)
/****************************************************************************
Denne mottar beskjeder fra Windows om innholdet av clipboard har forandret
seg. Den sender ogsσ beskjeden videre til andre vinduer som er med i
clipboardviewer kjeden.
TMessage& Msg Inneholder de aktuelle parametre som sendes videre.
Kodet av: MK 25.04.92
*****************************************************************************/
{
HMENU hMenu;
// Hvis flere er med i clipboardviewer kjeden, send beskjeden
// videre.
if (hwndNextViewer)
SendMessage(hwndNextViewer, Msg.Message, Msg.WParam, Msg.LParam);
// Sjekk om det er kommet noen DIB i clipboard og muliggj°r
// Paste i vσr meny hvis sσ er tilfelle.
hMenu=GetMenu(HWindow);
EnableMenuItem(hMenu, CM_EDITPASTE, IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
}
void TMainWindow::WMChangeCBChain(TMessage& Msg)
/****************************************************************************
Mottar beskjed om at det er skjedd en forandring i clipboardviewer
kjeden og oppdaterer den nye kjeden. Sender ogsσ beskjeden videre til
andre clipboardviewers.
TMessage& Msg Inneholder de aktuelle parametre som sendes videre.
Kodet av: MK 25.04.92
*****************************************************************************/
{
if (Msg.WParam==hwndNextViewer)
hwndNextViewer=LOWORD(Msg.LParam);
else if (hwndNextViewer)
SendMessage(hwndNextViewer, Msg.Message, Msg.WParam, Msg.LParam);
}
void TMainWindow::CreateClipboardChild()
/****************************************************************************
Denne fors°ker σ opprette et TPictureWindow objekt fra DIBen som ligger
i clipboard. Den sjekker om DIBen har 8 bits pr pixel, som er det eneste
vi supporterer hittil.
Kodet av: MK 25.04.92
*****************************************************************************/
{
HANDLE hCbdMem, hMem;
char huge *hpCbdMem, huge *hpMem;
WORD wSize;;
DWORD dwSize;
BITMAPINFO *lpNewBmpInfo;
int i, iY;
char acTemp[40];
long Count, lSize;
HCURSOR hcrOld;
OpenClipboard(HWindow);
// Er DIBen i clipboard fortsatt tilgjengelig?
if (IsClipboardFormatAvailable(CF_DIB))
{
// Fσ en handle til DIBen
hCbdMem = GetClipboardData(CF_DIB);
if (hCbdMem!=NULL)
{
hcrOld = SetCursor(hcrWait);
dwSize = GlobalSize(hCbdMem);
hpCbdMem = (char huge *)GlobalLock(hCbdMem);
// Regn ut st°rrelsen pσ BITMAPINFO strukturen (inkludert
// paletten)
wSize = sizeof(BITMAPINFOHEADER) + ((1 << hpCbdMem[14])*sizeof(RGBQUAD));
// Alloker minne til denne
lpNewBmpInfo = (BITMAPINFO *)new char[wSize];
// Kopier strukturen fra clipboard
_fmemcpy(&lpNewBmpInfo[0], &hpCbdMem[0], wSize);
// Hvis 8 bits pr pixel
if (lpNewBmpInfo->bmiHeader.biBitCount==8)
{
// dwSize lik st°rrelsen pσ bildet.
dwSize -= wSize;
// Alloker minne til data fra clipboard
hMem = GlobalAlloc(GMEM_PROFFTDATA, dwSize+MS_BUG);
if (hMem!=NULL)
{
hpMem = (char huge *)GlobalLock(hMem);
lSize = dwSize;
// Sett hpCbdMem til σ peke pσ starten av bildedataene
hpCbdMem=&hpCbdMem[wSize];
// Kopier data byte for byte fra clipboard
for (Count=0;Count<lSize;Count++)
*hpMem++=*hpCbdMem++;
GlobalUnlock(hMem);
// Opprett nytt TPictureWindow objekt..
CreateChild("<Clipboard>", lpNewBmpInfo, hMem);
}
else
{
delete lpNewBmpInfo;
GlobalFree(hMem);
MessageBox(HWindow, "Paste: Error allocating memory for clipboard data",
ERROR_CAPTION, MB_OK);
}
GlobalUnlock(hCbdMem);
}
else
{
delete lpNewBmpInfo;
MessageBox(HWindow, "Paste: Sorry, only 8 bits pr. pixel DIB format supported.",
"PROfft - Warning", MB_ERROR);
}
}
CloseClipboard();
SetCursor(hcrOld);
}
}
// Denne brukes for σ lette arbeidet med σ aksessere minnet direkte
// i blokker st°rre enn 64K. Brukes av GetBitmapData()
extern "C" {
void FAR PASCAL __ahIncr();
}
void TMainWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
/****************************************************************************
Leser inn selve bilderσdataene fra en bitmap fil. Brukes av OpenDIB().
int TheFile Handle til filen.
HANDLE BitsHandle Handle til minneblokken som skal motta dataene (mσ
vµre allokert pσ forhσnd).
long BitsByteSize Antall bytes som skal leses inn.
Kodet av: MK 03.04.92
*****************************************************************************/
{
long Count;
long Start, ToAddr, Bits;
Start = 0L;
Bits = (long)GlobalLock(BitsHandle);
Count = BitsByteSize - Start;
// Leser inn dataene fortl°pende
while ( Count > 0 )
{
// Regner ut adressen som skal motta dataene i minneblokken
ToAddr = MAKELONG(LOWORD(Start),
HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
if ( Count > 0x4000 )
Count = 0x4000;
_lread(TheFile, (LPSTR)ToAddr, (WORD)Count);
Start = Start + Count;
Count = BitsByteSize - Start;
}
GlobalUnlock(BitsHandle);
}
void TMainWindow::WriteBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
/****************************************************************************
Skriver ut selve bilderσdataene til en bitmap fil. Brukes av CMFileSaveAs().
int TheFile Handle til filen.
HANDLE BitsHandle Handle til minneblokken som skal motta dataene (mσ
vµre allokert pσ forhσnd).
long BitsByteSize Antall bytes som skal leses inn.
Kodet av: MK 25.04.92
*****************************************************************************/
{
long Count;
long Start, FromAddr, Bits;
BOOL bFailed;
Start = 0L;
Bits = (long)GlobalLock(BitsHandle);
Count = BitsByteSize - Start;
bFailed = FALSE;
while (( Count > 0 ) && (!bFailed))
{
FromAddr = MAKELONG(LOWORD(Start),
HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
if ( Count > 0x4000 )
Count = 0x4000;
if (_lwrite(TheFile, (LPSTR)FromAddr, (WORD)Count)<=0)
bFailed = TRUE;
Start = Start + Count;
Count = BitsByteSize - Start;
}
if (bFailed)
MessageBox(HWindow, "Save: Write to disk failed (disk full?).", ERROR_CAPTION, MB_OK);
GlobalUnlock(BitsHandle);
}
BOOL TMainWindow::OpenDIB(int TheFile, LPSTR FileName)
/****************************************************************************
Fors°ker σ laste inn en Windows DIB fil.
int TheFile Handle til filen.
LPSTR FileName Filnavnet som skal leses inn.
Returnerer: TRUE Hvis formatet er kjent og kan leses inn.
FALSE ellers.
Kodet av: MK 03.04.92
*****************************************************************************/
{
WORD bitCount;
WORD size;
long longWidth;
HDC DCHandle;
LPSTR BitsPtr;
BITMAPINFO *BitmapInfo;
HANDLE BitsHandle , NewBitmapHandle;
DWORD NewPixelWidth , NewPixelHeight;
BOOL retval;
retval= TRUE;
if (_llseek(TheFile, 28, 0)!=-1)
{
if (_lread(TheFile, (LPSTR)&bitCount, sizeof(bitCount))<(WORD)-1)
{
// Hvis det er 8 bits pr pixel som er det formatet vi supporterer.
if ( bitCount == 8 )
{
// Allokerer plass til en ny bildestruktur
size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
BitmapInfo = (BITMAPINFO *)new char[size];
// Leser dataene fra fil inn i den nye strukturen
_llseek(TheFile, sizeof(BITMAPFILEHEADER), 0);
_lread(TheFile, (LPSTR)BitmapInfo, size);
NewPixelWidth = BitmapInfo->bmiHeader.biWidth;
NewPixelHeight = BitmapInfo->bmiHeader.biHeight;
// Regner ut bytes pr line.
longWidth = (((NewPixelWidth * bitCount) + 31)/32) * 4;
// Regner ut bildest°rrelsen.
BitmapInfo->bmiHeader.biSizeImage = longWidth * NewPixelHeight;
// Rydder opp i minnet f°r vi fors°ker σ allokere minne til et
// nytt bitmap bilde.
GlobalCompact(-1);
// Allokerer minne til et nytt bilde.
BitsHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
BitmapInfo->bmiHeader.biSizeImage+MS_BUG);
if (BitsHandle!=NULL)
{
// Leser inn bildedataene.
GetBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
CreateChild(FileName, BitmapInfo, BitsHandle);
}
else
{
MessageBox(HWindow, "Open: Out of memory", ERROR_CAPTION,
MB_ERROR);
retval = FALSE;
}
}
else
{
MessageBox(HWindow, "Open: Only 8 bits pr. pixel DIB format supported", ERROR_CAPTION,
MB_ERROR);
retval = FALSE;
}
}
else
{
MessageBox(HWindow, "Open: Error reading file", ERROR_CAPTION,
MB_ERROR);
retval = FALSE;
}
}
else
{
MessageBox(HWindow, "Open: Error reading file", ERROR_CAPTION,
MB_ERROR);
retval = FALSE;
}
return retval;
}
BOOL TMainWindow::LoadBitmapFile(LPSTR Name)
/****************************************************************************
Fors°ker σ laste inn en Windows DIB fil. Tester om filen er en Window
DI bitmap og fors°ker σ laste den hvis sσ er tilfelle.
LPSTR FileName Filnavnet som skal leses inn.
Returnerer: TRUE Hvis formatet er kjent og kan leses inn.
FALSE ellers.
Kodet av: MK 03.04.92
*****************************************************************************/
{
int TheFile;
long TestWin30Bitmap;
char ErrorMsg[50] = "";
BOOL retval;
TheFile = _lopen(Name, OF_READ);
if ( TheFile != -1 )
{
_llseek(TheFile, 14, 0);
_lread(TheFile, (LPSTR)&TestWin30Bitmap, sizeof(TestWin30Bitmap));
if ( TestWin30Bitmap == 40 )
if ( OpenDIB(TheFile, Name) )
// AdjustScroller();
;
else
strcpy(ErrorMsg,
"Open: Unable to create Windows 3.0 bitmap from file");
else
strcpy(ErrorMsg, "Open: Not a Windows 3.0 bitmap file");
_lclose(TheFile);
}
else
strcpy(ErrorMsg, "Open: Cannot open bitmap file");
if ( ErrorMsg[0] == '\0' )
retval= TRUE;
else
{
MessageBox(HWindow, ErrorMsg, ERROR_CAPTION, MB_ERROR);
retval= FALSE;
}
return retval;
}
BOOL TMainWindow::SaveBitmapFile(LPSTR Name)
/****************************************************************************
Fors°ker σ lagre bitmapbildet i det aktive vinduet til en fil.
LPSTR Name Filnavnet som det skal lagres til.
Returnerer: TRUE Hvis lagringen gikk ok.
FALSE ellers.
Kodet av: MK 03.04.92
*****************************************************************************/
{
int TheFile, iBytesPrLine;
long TestWin30Bitmap, lSize;
char ErrorMsg[120] = "%s already exists.\nDo you wish to replace this file?";
char Temp[120];
BITMAPFILEHEADER bmpHeader;
int iMsgBox, iWritten;
BOOL retval, bFailed;
TGenericPicWindow *ptActive;
HCURSOR hcrOld;
TheFile = _lopen(Name, OF_READWRITE);
iMsgBox = IDOK;
retval = TRUE;
bFailed = FALSE;
// Tester om filen finnes fra f°r.
if (TheFile != -1)
{
wsprintf(Temp, ErrorMsg, Name);
iMsgBox = MessageBox(HWindow, Temp, "PROfft - Warning", MB_OKCANCEL);
}
else
// Hvis ikke, opprett den
{
TheFile = _lcreat(Name, 0);
if (TheFile == -1)
{
MessageBox(HWindow, "Save: Could not create output file", ERROR_CAPTION, MB_OK);
retval = FALSE;
}
}
// Hvis filen ikke fantes, eller den fantes og brukeren °nsket σ
// overskrive den.
if (iMsgBox==IDOK)
{
hcrOld = SetCursor(hcrWait);
// Fyll ut BITMAPFILEHEADER og BITMAPINFO strukturene
ptActive = ((TGenericPicWindow *)ActiveChild);
lSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+(1 << ptActive->bmpInfo->bmiHeader.biBitCount)
*sizeof(RGBQUAD);
lstrcpy((LPSTR)&bmpHeader, "BM");
iBytesPrLine = (((ptActive->bmpInfo->bmiHeader.biWidth
*ptActive->bmpInfo->bmiHeader.biBitCount) + 31) / 32) * 4;
bmpHeader.bfSize=lSize+(((DWORD)iBytesPrLine
*(DWORD)ptActive->bmpInfo->bmiHeader.biHeight));
bmpHeader.bfReserved1=0;
bmpHeader.bfReserved2=0;
// Skriv filheaderen til disk, sjekk for feil
if (_lwrite(TheFile, (LPSTR) &bmpHeader, sizeof(BITMAPFILEHEADER))<=0)
bFailed=TRUE;
// Skriv bildestrukturen til disk, sjekk for feil
if (_lwrite(TheFile, (LPSTR) ptActive->bmpInfo, sizeof(BITMAPINFOHEADER)
+(1 << ptActive->bmpInfo->bmiHeader.biBitCount)
*sizeof(RGBQUAD))<=0)
bFailed=TRUE;
// Hvis skrivingen over gikk bra, lagre selve bildet.
if (!bFailed)
// Skriv bildet til disk.
WriteBitmapData(TheFile, ptActive->hBitmap,
ptActive->bmpInfo->bmiHeader.biSizeImage);
_lclose(TheFile);
SetCursor(hcrOld);
}
if (bFailed)
{
MessageBox(HWindow, "Save: Write to disk failed", ERROR_CAPTION, MB_OK);
retval = FALSE;
}
return retval;
}